package com.CMUBiS.Depreciated;

import java.security.MessageDigest;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Date;
import java.util.Random;

import com.CMUBiS.Data.GlobalVars;

public abstract class Database {
	
	private Boolean verbose = GlobalVars.verbose;
	private String url = null;
	private String driver = null;
	private String userName = null; 
	private String password = null;
	private Connection dbConnection = null;
	private Random generator = new Random();
	
	/** Initializes the database connection
	 * @author John I. Payne
	 * @param verbose_	If true details about the db connection and communication are given
	 * @param driver_	jdbc data base driver eg "com.mysql.jdbc.Driver"
	 * @param url_		Database location eg "jdbc:mysql://IP_ADDRESS/DATABASE_NAME" 
	 * @param userName_	username for database 
	 * @param password_	password for database 
	 */
	public void initalizeConnection(Boolean verbose_, String driver_, String url_, String userName_, String password_){
		setVerbose(verbose_);
		driver = driver_;
		url = url_;
		userName = userName_;
		password = password_;
	}
	
	/** Creates the database connection
	 * @author John I. Payne
	 * @return	success (true) or failure (false) of connection creation
	 */
	public Boolean createConnection(){
		Boolean success=true;
		try {
			Class.forName(driver).newInstance();
			dbConnection=DriverManager.getConnection(url,userName,password);
			} catch (Exception e) {
				success = false;
				if(getVerbose()){
					System.out.print("Could not connect to database...  " + e.getMessage()+"\n");
					}
				}
		if(getVerbose()&success){
			System.out.println("Database connected successfully!");
			}
		return success;
	}
	
	/** Gets the database connection object
	 * @author John I. Payne
	 * @return	the database connection object
	 */
	public Connection getDbConnection() {
		return dbConnection;
	}
	
	
	/** Sets the verbose variable
	 * @author John I. Payne
	 * @param verbose Boolean variable indicated verbose cmdline output
	 * @return	verbose variable
	 */
	public void setVerbose(Boolean verbose_) {
		verbose = verbose_;
	}

	/** Gets the verbose variable
	 * @author John I. Payne
	 * @return	verbose variable
	 */
	public Boolean getVerbose() {
		return verbose;
	}
	
	/** Gets a random integer from the generator
	 * @author John I. Payne
	 * @return	random integer
	 */
	public int getRand() {
		return generator.nextInt();
	}
	
	/** Creates an authentication token from the md5 of a random int + the user's id + the current time in ms
	 * @param id	User's id
	 * 
	 * @return		authToken
	 */
	public String authToken(int id){
		int rand = getRand();
		Date date = new Date();
		
		String authToken = Math.abs(rand)+((Integer)id).toString()+date.getTime();
		
		byte[] bytesOfMessage=null;
		MessageDigest md = null;
		
		try {
			bytesOfMessage = authToken.getBytes("UTF-8");
			md = MessageDigest.getInstance("MD5");
		} catch (Exception e) {
			if(getVerbose()){
				System.out.print("AuthToken generation failed... " + e.getMessage()+"\n");
				}
		}
		byte[] thedigest = md.digest(bytesOfMessage);
		authToken = thedigest.toString();
		if(getVerbose()){
			System.out.print("AuthToken for " + userName + " successfully generated.\n");
		}
		
		return authToken;
		}
	
	public Boolean checkConnection(){
		Connection dbconn = getDbConnection();
		if(dbconn==null){
			initalizeConnection(true,"com.mysql.jdbc.Driver","jdbc:mysql://10.9.78.1/cmubis","root","testtest");
			createConnection();
		} else{
			
			try {
				if(getDbConnection().isClosed()){
					createConnection();}
			} catch (Exception e) {
				if(getVerbose()){
					System.out.print("Could not check DbConnection... " + e.getMessage()+"\n");
					return false;
					}
			}
		}
		return true;
	}
	
	/** Authenticates user
	 * @author John I. Payne
	 * @param userName	User's username
	 * @param password	User's password 
	 * 
	 * @return			authToken if successful or null if failure
	 */
	public abstract String login(String userName, String password);

	/** Validates user's authentication token
	 * @author John I. Payne
	 * @param userName	User's username
	 * @param authToken	User's authentication token 
	 * 
	 * @return			true if successful or false if failure
	 */
	public abstract Boolean checkAuthToken(String userName, String authToken);

	
}
	
